package com.example.backend.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.backend.common.api.ResultCode;
import com.example.backend.common.exception.BusinessException;
import com.example.backend.dto.RoleDTO;
import com.example.backend.entity.Role;
import com.example.backend.entity.RolePermission;
import com.example.backend.entity.UserRole;
import com.example.backend.mapper.RoleMapper;
import com.example.backend.mapper.RolePermissionMapper;
import com.example.backend.mapper.UserRoleMapper;
import com.example.backend.service.RoleService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 角色服务实现类
 */
@Service
@RequiredArgsConstructor
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements RoleService {
    
    private final UserRoleMapper userRoleMapper;
    private final RolePermissionMapper rolePermissionMapper;
    
    @Override
    public List<Role> getUserRoles(Long userId) {
        return baseMapper.selectUserRoles(userId);
    }
    
    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean assignUserRoles(Long userId, List<Long> roleIds) {
        // 先删除用户原有角色
        userRoleMapper.delete(new LambdaQueryWrapper<UserRole>()
                .eq(UserRole::getUserId, userId));
        
        // 批量保存新的角色关联
        List<UserRole> userRoles = roleIds.stream()
                .map(roleId -> {
                    UserRole userRole = new UserRole();
                    userRole.setUserId(userId);
                    userRole.setRoleId(roleId);
                    return userRole;
                }).collect(Collectors.toList());
        
        return !userRoles.isEmpty() && userRoleMapper.insertBatch(userRoles) > 0;
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void createRole(RoleDTO roleDTO) {
        // 1. 检查角色编码是否存在
        if (checkRoleCodeExists(roleDTO.getCode())) {
            throw new BusinessException(ResultCode.ROLE_CODE_EXISTS);
        }
        
        // 2. 创建角色
        Role role = new Role();
        role.setName(roleDTO.getName());
        role.setCode(roleDTO.getCode());
        role.setDescription(roleDTO.getDescription());
        role.setStatus(roleDTO.getStatus() != null ? roleDTO.getStatus() : 1);
        role.setSort(roleDTO.getSort() != null ? roleDTO.getSort() : 0);
        
        if (!save(role)) {
            throw new BusinessException(ResultCode.FAILED);
        }
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateRole(RoleDTO roleDTO) {
        // 1. 检查角色是否存在
        Role existingRole = getById(roleDTO.getId());
        if (existingRole == null) {
            throw new BusinessException(ResultCode.ROLE_NOT_FOUND);
        }
        
        // 2. 如果修改了角色编码，检查是否存在
        if (!existingRole.getCode().equals(roleDTO.getCode()) 
                && checkRoleCodeExists(roleDTO.getCode())) {
            throw new BusinessException(ResultCode.ROLE_CODE_EXISTS);
        }
        
        // 3. 更新角色
        Role role = new Role();
        role.setId(roleDTO.getId());
        role.setName(roleDTO.getName());
        role.setCode(roleDTO.getCode());
        role.setDescription(roleDTO.getDescription());
        role.setStatus(roleDTO.getStatus());
        role.setSort(roleDTO.getSort());
        
        if (!updateById(role)) {
            throw new BusinessException(ResultCode.FAILED);
        }
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteRole(Long roleId) {
        // 1. 检查角色是否存在
        if (!checkRoleExists(roleId)) {
            throw new BusinessException(ResultCode.ROLE_NOT_FOUND);
        }
        
        // 2. 删除角色权限关联
        rolePermissionMapper.delete(new LambdaQueryWrapper<RolePermission>()
                .eq(RolePermission::getRoleId, roleId));
        
        // 3. 删除角色
        if (!removeById(roleId)) {
            throw new BusinessException(ResultCode.FAILED);
        }
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateRolePermissions(Long roleId, List<Long> permissionIds) {
        // 1. 检查角色是否存在
        if (!checkRoleExists(roleId)) {
            throw new BusinessException(ResultCode.ROLE_NOT_FOUND);
        }
        
        // 2. 删除原有权限
        rolePermissionMapper.delete(new LambdaQueryWrapper<RolePermission>()
                .eq(RolePermission::getRoleId, roleId));
        
        // 3. 添加新权限
        if (!permissionIds.isEmpty()) {
            List<RolePermission> rolePermissions = permissionIds.stream()
                    .map(permissionId -> {
                        RolePermission rolePermission = new RolePermission();
                        rolePermission.setRoleId(roleId);
                        rolePermission.setPermissionId(permissionId);
                        return rolePermission;
                    })
                    .toList();
            
            if (rolePermissionMapper.insertBatch(rolePermissions) <= 0) {
                throw new BusinessException(ResultCode.FAILED);
            }
        }
    }
    
    @Override
    public List<Long> getRolePermissionIds(Long roleId) {
        return rolePermissionMapper.selectList(new LambdaQueryWrapper<RolePermission>()
                        .eq(RolePermission::getRoleId, roleId))
                .stream()
                .map(RolePermission::getPermissionId)
                .toList();
    }
    
    /**
     * 检查角色编码是否存在
     */
    private boolean checkRoleCodeExists(String code) {
        return count(new LambdaQueryWrapper<Role>()
                .eq(Role::getCode, code)) > 0;
    }
    
    /**
     * 检查角色是否存在
     */
    private boolean checkRoleExists(Long roleId) {
        return getById(roleId) != null;
    }
} 